// common/db.js
const mysql = require('mysql2');
const config = require('../config/config');

const pool = mysql.createPool(config.db);
pool.on('acquire', (conn) => {
  console.log(`[POOL] 连接获取 ${conn.threadId} 空闲: ${pool._freeConnections.length}`);
});
module.exports = {
    // query 方法用于执行单个 SQL 查询语句，并返回结果
    query: (sql, params, callback) => {
        pool.getConnection((err, conn) => {
            if (err) {
                callback(err, null);
            } else {
                conn.query(sql, params, (err1, results) => {
                    conn.release();
                    callback(err1, results);
                })
            }
        })
    },
    // dbTransaction 方法用于执行多个 SQL 语句作为事务，并返回结果
    // 注意：dbTransaction 方法要求所有 SQL 语句必须成功才算成功，如果有任何一个 SQL 语句失败，则整个事务失败
    // sqlVsParams:数组，元素为 sql语句及参数组成的对象，如[{sql:'',params:[]}]
    
    dbTransaction: (sqlVsParams, callback) => {
        pool.getConnection((err, conn) => {
            if (err) {
                return callback(err, null);
            }
            conn.beginTransaction(async (err1) => {
                if (err1) {
                    conn.release();
                    return callback(err1, null);
                }
                let results = [];
                try {
                    for (let item of sqlVsParams) {
                        // 用 promise 包装 query
                        const res = await new Promise((resolve, reject) => {
                            conn.query(item.sql, item.params, (err2, results1) => {
                                if (err2) return reject(err2);
                                resolve(results1);
                            });
                        });
                        results.push(res);
                    }
                    conn.commit((err4) => {
                        conn.release();
                        if (err4) return callback(err4, null);
                        return callback(null, results);
                    });
                } catch (err2) {
                    conn.rollback(() => {
                        conn.release();
                        return callback(err2, null);
                    });
                }
            });
        });
    }
}